/****************************************************************************/
/* File: scs-application.cpp                                                */
/* Desc: Implementation file for the core application type                  */
/* Created: 2014-11-12                                                      */
/* Revised: 2014-11-14                                                      */
/* Authors: Sterling P. de Mille                                            */
/****************************************************************************/

// specification file
#include "scs-application.h"

SCSapplication* SCSapplication::m_pkSingleton = NULL;

SCSapplication::SCSapplication ()
{
	assert(!m_pkSingleton);
	m_pkSingleton = this;

	m_sTitle = "Application";
	m_sVersion = "1.0.0";
	m_iRunning = SCS_FALSE;
}
SCSapplication::~SCSapplication ()
{
	return;
}

SCSerror SCSapplication::Create (const SCSstring sTitle, const SCSstring sVersion, SCSint iSizeX, SCSint iSizeY, SCSbool iFullscreen)
{
	m_sTitle = sTitle;
	m_sVersion = sVersion;
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
	try {
		assert(SCSdisplay::Singleton()->Create(iSizeX, iSizeY, iFullscreen) == 0);
	} catch (SCSint e) {
		cerr << "Application could not create display (" << e << ")." << endl;
	}
	SDL_WM_SetCaption(m_sTitle.c_str(), m_sTitle.c_str());
	InitOpenGL();

	return SCS_ERROR_NONE;
}

SCSerror SCSapplication::Create (const SCSstring sTitle, const SCSstring sVersion, SCSbool iFullscreen)
{
	m_sTitle = sTitle;
	m_sVersion = sVersion;
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
	try {
		assert(SCSdisplay::Singleton()->Create(iFullscreen) == 0);
	} catch (SCSint e) {
		cerr << "Application could not create display (" << e << ")." << endl;
	}
	SDL_WM_SetCaption(m_sTitle.c_str(), m_sTitle.c_str());
	InitOpenGL();

	return SCS_ERROR_NONE;
}

void SCSapplication::InitOpenGL ()
{
	switch(SCSdisplay::Singleton()->BitDepth()) {
	case 32:
	    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
	    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
	    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
	    SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
	    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 32 );
	    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
	    break;
	case 24:
		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );
		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
		break;
	case 16:
	    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
	    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 6 );
	    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
	    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
	    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
	    break;
	default:
	    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
	    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
	    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
	    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );
	    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
	    break;
	}
}

SCSapplication* SCSapplication::Singleton ()
{
	return m_pkSingleton;
}

SCSstring SCSapplication::Title () const
{
	return m_sTitle;
}
SCSstring SCSapplication::Version () const
{
	return m_sVersion;
}

void SCSapplication::Init () {
	return;
}
void SCSapplication::Load () {
	return;
}

void SCSapplication::Fullscreen (const SCSbool iEnable) {
	if (iEnable) {
		SDL_WM_ToggleFullScreen(SCSdisplay::Singleton()->FrameBuffer());
	} else {
		SDL_WM_ToggleFullScreen(NULL);
	}
}
void SCSapplication::Cursor (const SCSbool iEnable) {
	if (iEnable) {
		SDL_ShowCursor(SDL_ENABLE);
	} else {
		SDL_ShowCursor(SDL_DISABLE);
	}
}

SCSbool SCSapplication::Running () const {
	return m_iRunning;
}

void SCSapplication::Start () {
	m_iRunning = SCS_TRUE;
	Init();
	Load();
	while (m_iRunning) {
		BeginFrame();
		Frame();
		EndFrame();
	}
	Unload();
	Fullscreen(SCS_FALSE);
	SDL_Quit();
}
void SCSapplication::Stop () {
	m_iRunning = SCS_FALSE;
}

void SCSapplication::BeginFrame () {
	SCSdisplay::Singleton()->Clear();
	SCSclock::Singleton()->Update();
}
void SCSapplication::EndFrame () {
	SCSdisplay::Singleton()->Update();
}
void SCSapplication::Frame () {
	return;
}
